/**
 * Created by zhangbo on 27/01/14.
 */

var CesiumSelect = (function () {

	/**
	 * 构造 CesiumSelect
	 */
    function _(cesiumViewer, opt) {
        var option = this._option = opt || {infowindow: {offset: {x: 0, y: -10}}};
        var viewer = this._viewer = cesiumViewer;
        var infoWindow = this._infoWindow = new InfoWindow(viewer, this._option.infowindow);
        var toolTipWindow = this._toolTipWindow = new InfoWindow(viewer, this._option.infowindow);
        var selectedObject = this._selectedObject = null;
        var toolTipObject = this._toolTipObject = null;
        var hoverObject = this._hoverObject = null;
        
        this._selectedFeature = {
        	feature: undefined,
        	entity: undefined,
            originalColor: new Cesium.Color()
        };
        
        this._highlightedFeature = {
            feature: undefined,
            entity: undefined,
            originalColor: new Cesium.Color()
        };
        
        var handler = this._handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        var clickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // this._infoWindow.showAt(Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3()), primitiveId, primitiveId);
        // this._infoWindow.bindTarget(pickedObject);
        // this._infoWindow.setVisible(true);
        viewer.scene.primitives.add(this._infoWindow);
        viewer.scene.primitives.add(this._toolTipWindow);
        infoWindow.closeHandler = function () {
        	_this.pop(false);
        	_this.focus(false);
//        	_this.focus(false, true);
        	_this._selectedObject = null;
    		if (Cesium.defined(_this._selectedFeature.feature)) {
        		_this._selectedFeature.feature.color = _this._selectedFeature.originalColor;
        		_this._selectedFeature.feature = undefined;
            }
    		if(Cesium.defined(_this._selectedFeature.entity)){
    			entityColorSet(_this._selectedFeature.entity, _this._selectedFeature.originalColor);
    			_this._selectedFeature.entity = undefined;
    		}
    		
    		// 模型轨迹
            Airport.ModelPath.drawPath(null);
            // 路径规划
            Airport.Route.clear();
        };
        toolTipWindow.closeHandler = function () {
        	_this.toolTip(false);
        };
        var _this = this;
        handler.setInputAction(function(click) {
            var pickedObject = viewer.scene.pick(click.position);
            // 模型轨迹
            Airport.ModelPath.drawPath(pickedObject);
            // 路径规划
            Airport.Route.drawPosition(viewer.scene.pickPosition(click.position));
            
            if (Cesium.defined(pickedObject)) {
            	_this._selectedObject = pickedObject;
            	_this._pickPosition = viewer.scene.pickPosition(click.position);
            	_this.onclick();
            	if(pickedObject instanceof Cesium.Cesium3DTileFeature){
                	
            		if (Cesium.defined(_this._selectedFeature.feature)) {
                		_this._selectedFeature.feature.color = _this._selectedFeature.originalColor;
                		_this._selectedFeature.feature = undefined;
                    }
            		if(Cesium.defined(_this._selectedFeature.entity)){
            			entityColorSet(_this._selectedFeature.entity, _this._selectedFeature.originalColor);
            			_this._selectedFeature.entity = undefined;
            		}
            		
                	// Select the feature if it's not already selected
                    if (_this._selectedFeature.feature === pickedObject) {
                        return;
                    }
                    
                    _this._selectedObject = undefined;
                    _this._pickPosition = viewer.scene.pickPosition(click.position);
                    _this._selectedFeature.feature = pickedObject;
                    // Save the selected feature's original color _.prototype.SelectedColor
                    if (pickedObject === _this._highlightedFeature.feature) {
                        Cesium.Color.clone(_this._highlightedFeature.originalColor, _this._selectedFeature.originalColor);
                        _this._highlightedFeature.feature = undefined;
                    } else {
                        Cesium.Color.clone(pickedObject.color, _this._selectedFeature.originalColor);
                    }
                    // Highlight newly selected feature
                    pickedObject.color = _this.SelectedColor;
                    
                    // 触发3D Tiles 选择事件
                	window.Events.trigger(window.Events.Cesium3DTileSelectedEvent, _this);
                	
                    return;
            	}
            	else if(pickedObject.id instanceof Cesium.Entity){
            		var entity = pickedObject.id;
            		if (Cesium.defined(_this._selectedFeature.feature)) {
                		_this._selectedFeature.feature.color = _this._selectedFeature.originalColor;
                		_this._selectedFeature.feature = undefined;
                    }
            		if(Cesium.defined(_this._selectedFeature.entity)){
            			entityColorSet(_this._selectedFeature.entity, _this._selectedFeature.originalColor);
            			_this._selectedFeature.entity = undefined;
            		}
            		
                	// Select the feature if it's not already selected
                    if (_this._selectedFeature.entity === entity) {
                        return;
                    }
                    _this._pickPosition = viewer.scene.pickPosition(click.position);
                    _this._selectedFeature.entity = entity;
                    // Save the selected feature's original color _.prototype.SelectedColor
                    if (entity === _this._highlightedFeature.entity) {
                        Cesium.Color.clone(_this._highlightedFeature.originalColor, _this._selectedFeature.originalColor);
                        _this._highlightedFeature.entity = undefined;
                    } else {
                        Cesium.Color.clone(entityColorGet(entity), _this._selectedFeature.originalColor);
                    }
                    entityColorSet(entity, _this.SelectedColor);
                    // 触发 Entity 选择事件
                	window.Events.trigger(window.Events.CesiumEntitySelectedEvent, _this);

                	return;
            	}
            	
//            	if((pickedObject.primitive instanceof Cesium.Model && Cesium.defined(pickedObject.primitive.isEdit) && pickedObject.primitive.isEdit)
//            	 ||(pickedObject.primitive instanceof Cesium.Billboard && Cesium.defined(pickedObject.id.isEdit) && pickedObject.id.isEdit)){
//            		//在可编辑状态
//            		return;
//            	}
            	if(!_this.isSelectObj(pickedObject)){
            		_this.pop(false);
//                    _this.focus(false, true);
                    _this.focus(false);

                	_this.pop(true);
                	_this.focus(true);
            	}
            	else{
                    _this.pop(false);
//                    _this.focus(false, true);
                    _this.focus(false);
                    _this._selectedObject = null;
            	}

            }
            else{
            	clickHandler(click);
            	
                _this.pop(false);
//                _this.focus(false, true);
                _this.focus(false);
                _this._selectedObject = null;
                if (Cesium.defined(_this._selectedFeature.feature)) {
            		_this._selectedFeature.feature.color = _this._selectedFeature.originalColor;
            		_this._selectedFeature.feature = undefined;
                }
        		if(Cesium.defined(_this._selectedFeature.entity)){
        			entityColorSet(_this._selectedFeature.entity, _this._selectedFeature.originalColor);
        			_this._selectedFeature.entity = undefined;
        		}
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // If the mouse is over the billboard, change its scale and color
        
        handler.setInputAction(function(movement) {
            var pickedObject = viewer.scene.pick(movement.endPosition);
            if (Cesium.defined(pickedObject)) {
            	if(pickedObject instanceof Cesium.Cesium3DTileFeature){
            		// If a feature was previously highlighted, undo the highlight
                    if (Cesium.defined(_this._highlightedFeature.feature)) {
                    	_this._highlightedFeature.feature.color = _this._highlightedFeature.originalColor;
                    	_this._highlightedFeature.feature = undefined;
                    }
            		if(Cesium.defined(_this._highlightedFeature.entity)){
            			entityColorSet(_this._highlightedFeature.entity, _this._highlightedFeature.originalColor);
            			_this._highlightedFeature.entity = undefined;
            		}
                    // Highlight the feature if it's not already selected.
                    if (pickedObject !== _this._selectedFeature.feature) {
                    	_this._highlightedFeature.feature = pickedObject;
                        Cesium.Color.clone(pickedObject.color, _this._highlightedFeature.originalColor);
                        pickedObject.color = _this.HoverColor;
                    }
            		return;
            	}
            	else if(pickedObject.id instanceof Cesium.Entity){
            		var entity = pickedObject.id;
            		if (Cesium.defined(_this._highlightedFeature.feature)) {
                    	_this._highlightedFeature.feature.color = _this._highlightedFeature.originalColor;
                    	_this._highlightedFeature.feature = undefined;
                    }
            		if(Cesium.defined(_this._highlightedFeature.entity)){
            			entityColorSet(_this._highlightedFeature.entity, _this._highlightedFeature.originalColor);
            			_this._highlightedFeature.entity = undefined;
            		}
            		if (entity !== _this._selectedFeature.entity) {
                    	_this._highlightedFeature.entity = entity;
                        Cesium.Color.clone(entityColorGet(entity), _this._highlightedFeature.originalColor);
                        entityColorSet(entity, _this.HoverColor);
                    }
            		return;
            	}
            	else{
            		if (Cesium.defined(_this._highlightedFeature.feature)) {
                    	_this._highlightedFeature.feature.color = _this._highlightedFeature.originalColor;
                    	_this._highlightedFeature.feature = undefined;
                    }
            		if(Cesium.defined(_this._highlightedFeature.entity)){
            			entityColorSet(_this._highlightedFeature.entity, _this._highlightedFeature.originalColor);
            			_this._highlightedFeature.entity = undefined;
            		}
            	}

            	//_this._selectedObject
            	if(_this._toolTipObject === pickedObject){
//            		_this.toolTip(false);
            	
            		//提示框
            		//_this._pickPosition = movement.startPosition;
            		var cartesian = viewer.scene.pickPosition(movement.endPosition);
            		if(cartesian){
            		  var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            			  
            		  var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
                      var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
                      var heightString = cartographic.height.toFixed(2);
            			//console.info(longitudeString,latitudeString,heightString);
            			
            			//var p0 = Cesium.Cartesian3.fromDegrees(108 + 11 / 60 + 6 / 3600, 22 + 36 / 60 + 29 / 3600, 20);
            			var p1 = Cesium.Cartesian3.fromDegrees(longitudeString, latitudeString, 20);
                		//console.info(p0);
            			_this._pickPosition = p1;
                		_this._toolTipWindow.setTarget(_this._toolTipObject);
                		//_this._toolTipWindow.showAt(p1, '', '');
                		_this.toolTip(true);
            		}
            	}else{
            		_this._toolTipObject = pickedObject;
            		//_this.toolTip(true);
            	}
            } else {
            	_this.toolTip(false);
            	_this._toolTipObject = null;
            	if (Cesium.defined(_this._highlightedFeature.feature)) {
                	_this._highlightedFeature.feature.color = _this._highlightedFeature.originalColor;
                	_this._highlightedFeature.feature = undefined;
                }
            	if(Cesium.defined(_this._highlightedFeature.entity)){
        			entityColorSet(_this._highlightedFeature.entity, _this._highlightedFeature.originalColor);
        			_this._highlightedFeature.entity = undefined;
        		}
            }
            _this.hover(pickedObject);
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        viewer.trackedEntityChanged.addEventListener(function(e){
        	console.log('track:'+e);
        }, this);
        viewer.selectedEntityChanged.addEventListener(function(e){
        	console.log('select:'+e);
        }, this);
    };
    // 选择模型
    _.prototype.select = function (target, position, color){
    	if(Cesium.defined(target)){
    		this.pop(false);
            this.focus(false);
            this._selectedObject = null;
    		if(target instanceof Cesium.Entity){
//            	this._selectedObject = this._viewer.scene.pick(Cesium.Cartesian2.fromCartesian3(entity.position));
            	this._selectedObject = target;
            	if(Cesium.defined(this._highlightedFeature.entity)){
        			entityColorSet(this._highlightedFeature.entity, this._highlightedFeature.originalColor);
        			this._highlightedFeature.entity = undefined;
        		}
            	// Select the feature if it's not already selected
                if (this._selectedFeature.entity === target) {
                    return;
                }

                if (target !== this._selectedFeature.entity) {
                	this._highlightedFeature.entity = target;
                    Cesium.Color.clone(entityColorGet(target), this._highlightedFeature.originalColor);
                    entityColorSet(target, this.HoverColor);
                }
                this._selectedFeature.entity = target;
                if(Cesium.defined(position)){
            		this._pickPosition = position;
            	}
            	
            	// 触发 Entity 选择事件
            	window.Events.trigger(window.Events.CesiumEntitySelectedEvent, this);
            	
//            	this.pop(true);
//            	this.focus(true);
//            	this.onclick();
    		}
    		else if(target instanceof Cesium.Cesium3DTileFeature){
//    			this._selectedFeature.feature = target;
    			if(Cesium.defined(position)){
            		this._pickPosition = position;
            	}
    			
    			if (Cesium.defined(this._selectedFeature.feature)) {
            		this._selectedFeature.feature.color = this._selectedFeature.originalColor;
            		this._selectedFeature.feature = undefined;
                }
        		
            	// Select the feature if it's not already selected
                if (this._selectedFeature.feature === target) {
                    return;
                }

                this._selectedFeature.feature = target;
                // Save the selected feature's original color _.prototype.SelectedColor
                if (target === this._highlightedFeature.feature) {
                    Cesium.Color.clone(this._highlightedFeature.originalColor, this._selectedFeature.originalColor);
                    this._highlightedFeature.feature = undefined;
                } else {
                    Cesium.Color.clone(target.color, this._selectedFeature.originalColor);
                }
                // Highlight newly selected feature
                target.color = color || this.SelectedColor;
                
                // 触发3D Tiles 选择事件
            	window.Events.trigger(window.Events.Cesium3DTileSelectedEvent, this);
    		}
    	}
        else{
            this.pop(false);
//            this.focus(false, true);
            this.focus(false);
            this._selectedObject = null;
        }
    };
    _.prototype.zoom = function(longitude, latitude, height, complete){
    	var positionCartographic = new Cesium.Cartographic(Cesium.Math.toRadians(longitude), Cesium.Math.toRadians(latitude), height * 0.5);
        var position = this._viewer.scene.globe.ellipsoid.cartographicToCartesian(positionCartographic);

        var camera = this._viewer.scene.camera;
        var heading = camera.heading;
        var pitch = camera.pitch;

        var offset = offsetFromHeadingPitchRange(heading, pitch, height * 2.0);

        var transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
        Cesium.Matrix4.multiplyByPoint(transform, offset, position);

        camera.flyTo({
            destination: position,
            orientation: {
                heading: heading,
                pitch: pitch
            },
            complete: typeof complete === 'function' ? complete(position) : undefined,
            easingFunction: Cesium.EasingFunction.QUADRATIC_OUT
        });
    }
    _.prototype.isSelectObj = function (selectedObject) {
    	var objectId = selectedObject.id;
    	if (typeof objectId === 'string') {//primitive model
    		return objectId === 'cesium_select' || objectId.indexOf('unselect') !== -1;
    	}
    	else if(typeof objectId === 'object'){
    		return objectId.id === 'cesium_select' || String(objectId.id).indexOf('unselect') !== -1;
    	}
    	return false;
    };
//    _.prototype.selectHander = function(position){
//    	if (Cesium.defined(this._selectedObject)) {
//            var objectId = this._selectedObject.id ? this._selectedObject.id : undefined;
//            if (typeof objectId === 'string') {//primitive model
//            	if(objectId.indexOf('pick_') === -1){
//            		var select = this._selectedObject.primitive['popBinding'];
//                    var attributes = this._selectedObject.primitive['attributes'];
//                    var name = this._selectedObject.primitive['name'];
//                    this._infoWindow.setTitle(name || objectId);
//                    if (isBinding) {
//                        this._infoWindow.bindTarget(this._selectedObject);
//                        this._infoWindow.setContent(attributes);
//                        this._infoWindow.setVisible(true);
//                    }
//                    else {
//                        this._infoWindow.setTarget(this._selectedObject);
//                        var boundingSphere = this._selectedObject.primitive.boundingSphere;
//                        var modelMatrix = this._selectedObject.primitive.modelMatrix;
//                        if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
//                            var position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//                            this._infoWindow.setContent(attributes);
//                            this._infoWindow.showAt(position, objectId, attributes);
//                        }
//                    }
//            	}
//            	else{//强制定义弹出点为当前选择点
//            		var name = this._selectedObject.primitive['name'];
//            		var attributes = this._selectedObject.primitive['attributes'];
//            		var position = this._pickPosition;
//            		this._infoWindow.setTarget(this._selectedObject);
//            		this._infoWindow.setContent(attributes);
//                    this._infoWindow.showAt(position, name, attributes);
//            	}
//            }
//            else if (typeof objectId === 'object') {//entity
//                var id = objectId.id;
//                var isBinding = objectId['popBinding'];
//                var attributes = objectId['attributes'];
//                var name = objectId['name'] || id;
//                var popPostion = null;
//
//                this._infoWindow.setTitle(name);
//                if (Cesium.defined(objectId.model)) {//entity model
//                    var boundingSphere = this._selectedObject.primitive.boundingSphere;
//                    var modelMatrix = this._selectedObject.primitive.modelMatrix;
//                    if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
//                        popPostion = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//                    }
//                }
//                else if (Cesium.defined(objectId.polylineVolume)) {//entity polylineVolume
//                    popPostion = this._pickPosition;
//                }
//                else if (Cesium.defined(objectId.ellipsoid)) {//entity ellipsoid
//                    popPostion = this._pickPosition;
//                }
//                else if (Cesium.defined(objectId.billboard)) {//entity billboard
//                    popPostion = this._pickPosition;
//                }
//
//                if (isBinding) {
//                    this._infoWindow.bindTarget(this._selectedObject);
//                    this._infoWindow.setContent(attributes);
//                    this._infoWindow.setVisible(true);
//                }
//                else {
//                    if (Cesium.defined(popPostion)) {
//                        this._infoWindow.setTarget(this._selectedObject);
//                        this._infoWindow.setContent(attributes);
//                        this._infoWindow.showAt(popPostion, name, attributes);
//                    }
//                }
//            }
//        }
//    	
//    };
    _.prototype.getCenter = function () {
        var centerObj = null;
        if (Cesium.defined(this._selectedObject)) {
            //{lat: 39, lng: 117, height: 1000, radius: 50};
            var objectId = this._selectedObject.id;
            if (this._selectedObject instanceof Cesium.Primitive || typeof objectId === 'string') {//primitive model
                var boundingSphere = this._selectedObject.primitive.boundingSphere;
                var modelMatrix = this._selectedObject.primitive.modelMatrix;
                //将笛卡尔坐标转换为三维地理坐标
                var cartographic = Cesium.Cartographic.fromCartesian(Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3()));//center Cartesian3
                var radius = boundingSphere.radius;
                centerObj = {
                    lat: Cesium.Math.toDegrees(cartographic.latitude),
                    lng: Cesium.Math.toDegrees(cartographic.longitude),
                    height: cartographic.height,
                    radius: radius
                };
            }
            else if (this._selectedObject instanceof Cesium.Entity || typeof objectId === 'object') {//entity model
                if (Cesium.defined(objectId.model)) {
                    var boundingSphere = this._selectedObject.primitive.boundingSphere;
                    var modelMatrix = this._selectedObject.primitive.modelMatrix;
                    if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
                        //将笛卡尔坐标转换为三维地理坐标
                        var cartographic = Cesium.Cartographic.fromCartesian(Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3()));//center Cartesian3
                        var radius = boundingSphere.radius;
                        centerObj = {
                            lat: Cesium.Math.toDegrees(cartographic.latitude),
                            lng: Cesium.Math.toDegrees(cartographic.longitude),
                            height: cartographic.height,
                            radius: radius
                        };
                    }
                }
                else if (Cesium.defined(objectId.polylineVolume)) {
                    var radius = objectId['radius'] || 5;
                    var position = this._pickPosition;
                    if (Cesium.defined(position)) {
                        var cartographic = Cesium.Cartographic.fromCartesian(position);//center Cartesian3
                        centerObj = {
                            lat: Cesium.Math.toDegrees(cartographic.latitude),
                            lng: Cesium.Math.toDegrees(cartographic.longitude),
                            height: cartographic.height - radius,
                            radius: radius * 2
                        };
                    }
                }
                else if (Cesium.defined(objectId.ellipsoid)) {
                    var position = new Cesium.Cartesian3(objectId.position._value.x, objectId.position._value.y, objectId.position._value.z);
                    var radius = Math.max(objectId.ellipsoid.radii._value.x, objectId.ellipsoid.radii._value.y) || 5;
                    if (Cesium.defined(position)) {
                        var cartographic = Cesium.Cartographic.fromCartesian(position);//center Cartesian3
                        centerObj = {
                            lat: Cesium.Math.toDegrees(cartographic.latitude),
                            lng: Cesium.Math.toDegrees(cartographic.longitude),
                            height: cartographic.height,
                            radius: radius * 2
                        };
                    }
                }
                else if (Cesium.defined(objectId.billboard)) {
                    var position = new Cesium.Cartesian3(objectId.position._value.x, objectId.position._value.y, objectId.position._value.z);
                    var imgWidth = this._selectedObject.primitive.width;
                    //未计算出绘制圆半径
                }
            }
//            else {
//                this._infoWindow.bindTarget(null);
//                this._infoWindow.setContent('');
//                this._infoWindow.setVisible(false);
//            }
        }
        return centerObj;
    };
    _.prototype.focus = function (isFocus, track) {
        const _this = this;
        if (isFocus) {
//        	var centerObj = {lat: 39, lng: 117, height: 1000, radius: 1000};
            var objectId = this._selectedObject.id;
            if (typeof objectId === 'object' && Cesium.defined(objectId.polylineVolume)) {
                var radius = objectId['radius'] || 5;
        		var thisPolylineVolume = objectId.polylineVolume;
        		var thisPVPositions = thisPolylineVolume.positions._value;
        		var hlPositions = [];
        		for(var i = 0; i < thisPVPositions.length; i++){
        			hlPositions.push(new Cesium.Cartesian3(thisPVPositions[i].x, thisPVPositions[i].y, thisPVPositions[i].z - 1));
        		}
        		function computeCircle(radius) {
                    var positions = [];
                    for (var i = 0; i < 360; i++) {
                        var radians = Cesium.Math.toRadians(i);
                        positions.push(new Cesium.Cartesian2(radius * Math.cos(radians), radius * Math.sin(radians)));
                    }
                    return positions;
                }
        		viewer.entities.add({
        			id: 'cesium_select',
                    polylineVolume: {
                        positions: hlPositions,
                        shape: computeCircle(radius + 1),
                        material: Cesium.Color.RED,
                    },
        		});
            }
            else if (typeof objectId === 'string' && objectId.indexOf('pick_') !== -1){

            }
            else {
                viewer.entities.add({
                    id: 'cesium_select',
                    polyline: {
                        positions: new Cesium.CallbackProperty(function (time, result) {
                            var centerObj = _this.getCenter();
                            return centerObj ? computeEllipsePositions(centerObj.lat, centerObj.lng, centerObj.height, centerObj.radius) : [];
                        }, false),
                        width: 3,
//                        material: Cesium.Color.RED
                        material: Cesium.Color.ORANGE
                    }
                });
            }
            if(track){
            	viewer.trackedEntity = this._selectedObject;
            }
        }
        else {
            viewer.selectedEntity = null;
            if(track){
            	viewer.trackedEntity = null;
            }
            viewer.entities.removeById('cesium_select');
        }
    };
    _.prototype.pop = function (isPop) {
        if (isPop) {
            if (Cesium.defined(this._selectedObject)) {
                var objectId = this._selectedObject.id ? this._selectedObject.id : undefined;
                if (this._selectedObject instanceof Cesium.Primitive || typeof objectId === 'string') {//primitive model
                	if(objectId.indexOf('pick_') === -1){
                		var isBinding = this._selectedObject.primitive?this._selectedObject.primitive['popBinding']:false;
                        var attributes = this._selectedObject.primitive?this._selectedObject.primitive['attributes']:'';
                        var name = this._selectedObject.primitive?this._selectedObject.primitive['name']:'';
                        this._infoWindow.setTitle(name || objectId);
                        if (isBinding) {
                            this._infoWindow.bindTarget(this._selectedObject);
                            this._infoWindow.setContent(attributes);
                            this._infoWindow.setVisible(true);
                        }
                        else {
                            this._infoWindow.setTarget(this._selectedObject);
                            var boundingSphere = this._selectedObject.primitive.boundingSphere;
                            var modelMatrix = this._selectedObject.primitive.modelMatrix;
                            if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
                                var position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//                                this._infoWindow.setContent(attributes);
                                this._infoWindow.showAt(position, objectId, attributes);
                            }
                        }
                	}
                	else{//强制定义弹出点为当前选择点
                		var name = this._selectedObject.primitive['name'];
                		var attributes = this._selectedObject.primitive['attributes'];
                		var position = this._pickPosition;
                		this._infoWindow.setTarget(this._selectedObject);
//                		this._infoWindow.setContent(attributes);
                        this._infoWindow.showAt(position, name, attributes);
                	}
                }
                else if (this._selectedObject instanceof Cesium.Entity || typeof objectId === 'object') {//entity
                    var id = objectId.id;
                    var isBinding = objectId['popBinding'];
                    var attributes = objectId['attributes'];
                    var name = objectId['name'] || id;
                    var popPostion = null;

                    this._infoWindow.setTitle(name);
                    if (Cesium.defined(objectId.model)) {//entity model
                        var boundingSphere = this._selectedObject.primitive.boundingSphere;
                        var modelMatrix = this._selectedObject.primitive.modelMatrix;
                        if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
                            popPostion = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
                        }
                    }
                    else if (Cesium.defined(objectId.polylineVolume)) {//entity polylineVolume
                        popPostion = this._pickPosition;
                    }
                    else if (Cesium.defined(objectId.ellipsoid)) {//entity ellipsoid
                        popPostion = this._pickPosition;
                    }
                    else if (Cesium.defined(objectId.billboard)) {//entity billboard
                        popPostion = new Cesium.Cartesian3(objectId.position._value.x, objectId.position._value.y, objectId.position._value.z);
                    }
                    else if (Cesium.defined(objectId.polygon)) {//entity polygon
                        popPostion = this._pickPosition;
                    }
                    else if (Cesium.defined(objectId.corridor)) {//entity polygon
                        popPostion = this._pickPosition;
                    }

                    if (isBinding) {
                        this._infoWindow.bindTarget(this._selectedObject);
                        this._infoWindow.setContent(attributes);
                        this._infoWindow.setVisible(true);
                    }
                    else {
                        if (Cesium.defined(popPostion)) {
                            this._infoWindow.setTarget(this._selectedObject);
//                            this._infoWindow.setContent(attributes);
                            this._infoWindow.showAt(popPostion, name, attributes);
                        }
                    }
                }
            }
        }
        else {
            this._infoWindow.bindTarget(null);
            this._infoWindow.setContent('');
            this._infoWindow.setVisible(false);
            this.focus(false);
        }
    };
    _.prototype.popWithInfo = function (isPop, name, content, binding) {
        if (isPop) {
            if(this._selectedFeature.feature instanceof Cesium.Cesium3DTileFeature){
            	this._infoWindow.setTitle(name);
                if (binding) {
                    this._infoWindow.bindTarget(this._selectedFeature.feature);
                    this._infoWindow.setContent(content);
                    this._infoWindow.setVisible(binding);
                }
                else {
                    this._infoWindow.setTarget(this._selectedFeature.feature);
//                    var boundingSphere = this._selectedFeature.feature.primitive.boundingSphere;
//                    var modelMatrix = this._selectedFeature.feature.primitive.modelMatrix;
//                    if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
//                        var position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//                        this._infoWindow.setContent(content);
//                        this._infoWindow.showAt(position, name, content);
//                    }
                    //this._infoWindow.setContent(content);
                    this._infoWindow.showAt(this._pickPosition, name, content);
                }
            }
            else if(this._selectedFeature.entity instanceof Cesium.Entity){
            	this._infoWindow.setTitle(name);
                if (binding) {
                    this._infoWindow.bindTarget(this._selectedFeature.entity);
                    this._infoWindow.setContent(content);
                    this._infoWindow.setVisible(binding);
                }
                else {
                    this._infoWindow.setTarget(this._selectedFeature.entity);
                    this._infoWindow.showAt(this._pickPosition, name, content);
                }
            }
        }
        else {
            this._infoWindow.bindTarget(null);
            this._infoWindow.setContent('');
            this._infoWindow.setVisible(false);
            this.focus(false);
        }
    };
    _.prototype.toolTip = function (isToolTip) {
    	if (isToolTip){
    		if (Cesium.defined(this._toolTipObject)) {
                var objectId = this._toolTipObject.id ? this._toolTipObject.id : undefined;
                if (typeof objectId === 'string') {//primitive model
                	if(objectId.indexOf('pick_') === -1){
                        var toolTips = this._toolTipObject.primitive['toolTips'];
                        if(Cesium.defined(toolTips)){
                        	var name = this._toolTipObject.primitive['name'];
                            this._toolTipWindow.setTitle(name || objectId);
                            this._toolTipWindow.setTarget(this._toolTipObject);
                            var boundingSphere = this._toolTipObject.primitive.boundingSphere;
                            var modelMatrix = this._toolTipObject.primitive.modelMatrix;
                            if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
                                var position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
                                this._toolTipWindow.setContent(toolTips);
                                this._toolTipWindow.showAt(position, objectId, toolTips);
                            }
                        }
                	}
                	else{//强制定义弹出点为当前选择点
                		var name = this._toolTipObject.primitive['name'];
                		var toolTips = this._toolTipObject.primitive['toolTips'];
                		if(Cesium.defined(toolTips)){
                    		var position = this._pickPosition;
                    		this._toolTipWindow.setTarget(this._toolTipObject);
                    		this._toolTipWindow.setContent(toolTips);
                            this._toolTipWindow.showAt(position, name, toolTips);
                		}
                	}
                }
                else if (typeof objectId === 'object') {//entity
                    var id = objectId.id;
                    var toolTips = objectId['toolTips'];
                    if(Cesium.defined(toolTips)){
                    	var name = objectId['name'] || id;
                        var popPostion = null;

                        this._toolTipWindow.setTitle(name);
                        if (Cesium.defined(objectId.model)) {//entity model
                            var boundingSphere = this._toolTipObject.primitive.boundingSphere;
                            var modelMatrix = this._toolTipObject.primitive.modelMatrix;
                            if (Cesium.defined(boundingSphere) && Cesium.defined(modelMatrix)) {
                                popPostion = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
                            }
                        }
                        else if (Cesium.defined(objectId.polylineVolume)) {//entity polylineVolume
                            popPostion = this._pickPosition;
                        }
                        else if (Cesium.defined(objectId.ellipsoid)) {//entity ellipsoid
                            popPostion = this._pickPosition;
                        }
                        else if (Cesium.defined(objectId.billboard)) {//entity billboard
                            popPostion = this._pickPosition;
                        }

                        if (Cesium.defined(popPostion)) {
                            this._toolTipWindow.setTarget(this._toolTipObject);
                            this._toolTipWindow.setContent(toolTips);
                            this._toolTipWindow.showAt(popPostion, name, toolTips);
                        }
                    }
                    
                }
            }
    	}
    	else{
    		this._toolTipWindow.bindTarget(null);
            this._toolTipWindow.setContent('');
            this._toolTipWindow.setVisible(false);
    	}
    	
    };
    _.prototype.onclick = function () {
    	if (Cesium.defined(this._selectedObject)) {
            var objectId = this._selectedObject.id ? this._selectedObject.id : undefined;
            if (typeof objectId === 'string') {//primitive model
            	if(objectId.indexOf('pick_') === -1){
                    var onclick = this._selectedObject.primitive['onclick'];
                    if (onclick && typeof onclick === 'function') {
                    	onclick(this._selectedObject, this.getCenter());
                    }
            	}
            	else{
            		var onclick = this._selectedObject.primitive['onclick'];
            		if (onclick && typeof onclick === 'function') {
                    	onclick(this._selectedObject, this.getCenter());
                    }
            	}
            }
            else if (typeof objectId === 'object') {//entity
                var id = objectId.id;
                var onclick = objectId['onclick'];
                if (onclick && typeof onclick === 'function') {
                	onclick(this._selectedObject, this.getCenter());
                }
            }
        }
    };
    _.prototype.hover = function(pickedObject){
    	if(Cesium.defined(pickedObject)) {
    		if (this._hoverObject !== pickedObject) {//primitive model
       			mouseOut(this._hoverObject);
    		}
			this._hoverObject = pickedObject;
			mouseIn(this._hoverObject);
    	}
    	else{
    		if(Cesium.defined(this._hoverObject)){
    			mouseOut(this._hoverObject);
    			this._hoverObject = null;
    		}
    	}
    };
    _.prototype.destroy = function () {
        this.pop(false);
        this.toolTip(false);
        this.focus(false);
        this._viewer.scene.primitives.remove(this._infoWindow);
        this._viewer.scene.primitives.remove(this._toolTipWindow);
        this._handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this._handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this._handler.destroy();
        this._handler = null;
    };
    
    _.prototype.HoverColor = Cesium.Color.CYAN;//00FFFF
    _.prototype.SelectedColor = Cesium.Color.DARKTURQUOISE;
    _.prototype.WarningColor_RED = Cesium.Color.fromCssColorString('#e93329');
    _.prototype.WarningColor_RED_CSS = '#e93329';
    _.prototype.WarningColor_ORANGE = Cesium.Color.fromCssColorString('#eb672c');
    _.prototype.WarningColor_ORANGE_CSS = '#eb672c';
    _.prototype.WarningColor_YELLOW = Cesium.Color.fromCssColorString('#f6e14b');
    _.prototype.WarningColor_YELLOW_CSS = '#f6e14b';
    _.prototype.WarningColor_BLUE = Cesium.Color.fromCssColorString('#2155f1');
    _.prototype.WarningColor_BLUE_CSS = '#2155f1';
    
    //==================
    // 设置 Entity 颜色
    //==================
    function entityColorSet(entity, color){
    	if (Cesium.defined(entity.model)) {//entity model
    		entity.model.color = color;
        }
        else if (Cesium.defined(entity.polylineVolume)) {//entity polylineVolume
        	entity.polylineVolume.material = color;
        }
        else if (Cesium.defined(entity.ellipsoid)) {//entity ellipsoid
        	entity.ellipsoid.material = color;
        }
        else if (Cesium.defined(entity.corridor)) {//entity billboard
//            entity.corridor.material = color;
        }
    }
    function entityColorGet(entity){
    	if (Cesium.defined(entity.model)) {//entity model
    		return entity.model.color;
        }
        else if (Cesium.defined(entity.polylineVolume)) {//entity polylineVolume
        	return entity.polylineVolume.material;
        }
        else if (Cesium.defined(entity.ellipsoid)) {//entity ellipsoid
        	return entity.ellipsoid.material;
        }
        else if (Cesium.defined(entity.corridor)) {//entity billboard
//        	return entity.corridor.material;
        }
    }

    //==================
    //计算外包圆
    //==================
    function computeEllipsePositions(centerLat, centerLon, height, radius) {
        for (var positions = [], angle = 0; 361 > angle; angle += 2) {//angle:f
            var positionObj = getLatlng(centerLat, centerLon, angle, radius);//positionObj:g
            // 1英尺 = 0.3048米
//            positions.push(Cesium.Cartesian3.fromDegrees(positionObj.longitude, positionObj.latitude, .3048 * height));
            positions.push(Cesium.Cartesian3.fromDegrees(positionObj.longitude, positionObj.latitude, height));
        }
        return positions
    }

    function getLatlng(centerLat, centerLon, angle, radius) {
        var centerLatRadians = toRadians(centerLat);
        var centerLonRadians = toRadians(centerLon);
        var angleRadians = toRadians(angle);
//        var e = 1852 * radius / 6378137;//1海里=1.852公里 1公里=1000米
        var e = radius / 6378137;//1海里=1.852公里 1公里=1000米
        var latitudeRadians = Math.asin(Math.sin(centerLatRadians) * Math.cos(e) + Math.cos(centerLatRadians) * Math.sin(e) * Math.cos(angleRadians)); //latitudeRadians:d
        return {
            latitude: toDegrees(latitudeRadians),
            longitude: toDegrees(centerLonRadians + Math.atan2(Math.sin(angleRadians) * Math.sin(e) * Math.cos(centerLatRadians), Math.cos(e) - Math.sin(centerLatRadians) * Math.sin(latitudeRadians)))
        }
    }

    function toRadians(degrees) {
        return Math.PI / 180 * degrees
    }

    function toDegrees(radians) {
        return 180 / Math.PI * radians
    }
    
	function mouseIn(mouseObject){
		if(Cesium.defined(mouseObject)){
			var objectId = mouseObject.id ? mouseObject.id : undefined;
			if (typeof objectId === 'string') {//primitive model
    			
    		}
    		else if (typeof objectId === 'object') {//entity
    			if (Cesium.defined(objectId.model)) {//entity model
    				
    			}
    			else if (Cesium.defined(objectId.billboard)) {//entity billboard
    				objectId.billboard.imageSubRegion = new Cesium.BoundingRectangle(30, 0, 30, 30);
                }
    		}
		}
	}
	
	function mouseOut(mouseObject){
		if(Cesium.defined(mouseObject)){
			var objectId = mouseObject.id ? mouseObject.id : undefined;
			if (typeof objectId === 'string') {//primitive model
    			
    		}
    		else if (typeof objectId === 'object') {//entity
    			if (Cesium.defined(objectId.model)) {//entity model
    				
    			}
    			else if (Cesium.defined(objectId.billboard)) {//entity billboard
    				objectId.billboard.imageSubRegion = new Cesium.BoundingRectangle(0, 0, 30, 30);
                }
    		}
		}
	}
	
    //==================
    // offset From HeadingPitchRange
    //==================
	function offsetFromHeadingPitchRange(heading, pitch, range) {
	    pitch = Cesium.Math.clamp(pitch, -Cesium.Math.PI_OVER_TWO, Cesium.Math.PI_OVER_TWO);
	    heading = Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO;

	    var pitchQuat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Y, -pitch);
	    var headingQuat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, -heading);
	    var rotQuat = Cesium.Quaternion.multiply(headingQuat, pitchQuat, headingQuat);
	    var rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat);

	    var offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X);
	    Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset);
	    Cesium.Cartesian3.negate(offset, offset);
	    Cesium.Cartesian3.multiplyByScalar(offset, range, offset);
	    return offset;
	}


    return _;
})();
